package com.linkgie.galaxyframework.templating.model.maven;

import java.util.Collection;
import java.util.Map;
import java.util.Objects;
import java.util.Properties;
import java.util.Set;

import com.linkgie.galaxyframework.utils.CollectionUtils;

public class MavenProperties implements Map<String, String> {

	private Properties properties = new Properties();

	public Set<String> getNames() {
		return properties.stringPropertyNames();
	}

	public String getPropertyValue(String name) {
		return properties.getProperty(name);
	}

	public Set<Property> getEntrySet() {
		return CollectionUtils.cast(properties.entrySet(), (entry) -> {
			return new Property((String) entry.getKey(), (String) entry.getValue());
		});
	}

	public void setProperty(String name, String value) {
		properties.setProperty(name, value);
	}
	


	@Override
	public int size() {
		return properties.size();
	}

	@Override
	public boolean isEmpty() {
		return properties.isEmpty();
	}

	@Override
	public boolean containsKey(Object key) {
		return properties.containsKey(key);
	}

	@Override
	public boolean containsValue(Object value) {
		return properties.containsValue(value);
	}

	@Override
	public String get(Object key) {
		return properties.getProperty((String) key);
	}
	
	@Override
	public String put(String key, String value) {
		throw new UnsupportedOperationException("Unsupport to modify!");
	}

	@Override
	public String remove(Object key) {
		throw new UnsupportedOperationException("Unsupport to remove!");
	}

	@Override
	public void putAll(Map<? extends String, ? extends String> m) {
		throw new UnsupportedOperationException("Unsupport to modify!");
	}

	@Override
	public Collection<String> values() {
		return CollectionUtils.cast(properties.values(), v -> (String)v);
	}

	@Override
	public Set<Entry<String, String>> entrySet() {
		return CollectionUtils.cast(getEntrySet());
	}


	@Override
	public void clear() {
		throw new UnsupportedOperationException("Unsupport to clear!");
	}

	@Override
	public Set<String> keySet() {
		return properties.stringPropertyNames();
	}


	public static class Property implements Entry<String, String>{

		private String name;

		private String value;

		public Property() {
		}

		public Property(String name, String value) {
			this.name = name;
			this.value = value;
		}

		public String getName() {
			return name;
		}
		
		@Override
		public String getKey() {
			return name;
		}

		@Override
		public String getValue() {
			return value;
		}

		@Override
		public String setValue(String value) {
			throw new UnsupportedOperationException("PropertEntry cann't be set!");
		}
		

		@Override
		public int hashCode() {
			return Objects.hashCode(name);
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj) {
				return true;
			}
			if (obj == null) {
				return false;
			}
			if (!(obj instanceof Property)) {
				return false;
			}
			Property other = (Property) obj;
			return Objects.equals(this.name, other.name);
		}

		@Override
		public String toString() {
			return String.format("%s=%s", this.name, this.value);
		}
	}

}
